package com.blood.modules.pregnancy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.blood.core.enums.MessageStatusEnum;
import com.blood.core.enums.PregnancyStatusEnum;
import com.blood.core.resp.GlobalResultStatus;
import com.blood.core.resp.ResponseResult;
import com.blood.core.util.DateUtil;
import com.blood.modules.pregnancy.dto.req.PregnancyGatherUserPageReq;
import com.blood.modules.pregnancy.dto.req.PregnancyMessagePageReq;
import com.blood.modules.pregnancy.dto.resp.PregnancyAdminDataResp;
import com.blood.modules.pregnancy.dto.resp.PregnancyGatherDataResp;
import com.blood.modules.pregnancy.dto.resp.PregnancyHomeInfoResp;
import com.blood.modules.pregnancy.dto.resp.PregnancyHomeMessageResp;
import com.blood.modules.pregnancy.mapper.PregnancyGatherInfoMapper;
import com.blood.modules.pregnancy.model.PregnancyGatherInfo;
import com.blood.modules.pregnancy.model.PregnancyMessage;
import com.blood.modules.pregnancy.model.PregnancyUser;
import com.blood.modules.pregnancy.service.IPregnancyGatherInfoService;
import com.blood.modules.pregnancy.service.IPregnancyHomeService;
import com.blood.modules.pregnancy.service.IPregnancyMessageService;
import com.blood.modules.pregnancy.service.IPregnancyUserService;
import com.blood.modules.system.service.ISysRoleAuthorityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 孕产主页Service业务层处理
 *
 * @author daoren
 * @date 2022-11-24 13:39:22
 */
@Service
public class PregnancyHomeServiceImpl implements IPregnancyHomeService {
    @Autowired
    private IPregnancyGatherInfoService pregnancyGatherInfoService;
    @Autowired
    private PregnancyGatherInfoMapper pregnancyGatherInfoMapper;
    @Autowired
    private IPregnancyUserService pregnancyUserService;
    @Autowired
    private IPregnancyMessageService pregnancyMessageService;
    @Autowired
    private ISysRoleAuthorityService sysRoleAuthorityService;

    @Override
    public ResponseResult<PregnancyHomeMessageResp> homeMessageInfo() {
        PregnancyHomeMessageResp messageResp = new PregnancyHomeMessageResp();
        PregnancyMessagePageReq req = new PregnancyMessagePageReq();
        req.setPageNo(1);
        req.setPageSize(3);
        //通知分页查询
        req.setType(MessageStatusEnum.ENABLE.getValue());
        messageResp.setMessageList(pregnancyMessageService.pageList(req));
        //代办分页查询
        req.setType(MessageStatusEnum.DIS_ENABLE.getValue());
        messageResp.setBacklogList(pregnancyMessageService.pageList(req));
        //查询未读消息
        PregnancyMessage newInfo = pregnancyMessageService.queryNewInfo();
        messageResp.setNewMessage(null != newInfo);
        return GlobalResultStatus.SUCCESS.toResult().response(messageResp);
    }

    @Override
    public ResponseResult<PregnancyGatherDataResp> getStatisticsData(Date date) {
        PregnancyGatherDataResp resp = new PregnancyGatherDataResp();
        //获取当天结束时间
        Date dayEnd = DateUtil.getAddDate(1, date);
        //获取昨日日期
        Date oneDayDate = DateUtil.getDownDayDate(1, date);
        //获取6日前期
        Date sixDayDate = DateUtil.getDownDayDate(6, date);
        //获7日前期
        Date sevenDayDate = DateUtil.getDownDayDate(7, date);
        //获取8日前期
        Date eightDayDate = DateUtil.getDownDayDate(8, date);
        //接收孕妇信息
        QueryWrapper<PregnancyUser> userQueryWrapper = new QueryWrapper<>();
        sysRoleAuthorityService.queryDataAuthority(userQueryWrapper);
        List<PregnancyUser> userList = pregnancyUserService.list(userQueryWrapper.select("DATE_FORMAT(create_time,'%Y-%m-%d') AS create_time, NULLIF(count(line_no),0) AS number")
                .ge("create_time", eightDayDate)
                .lt("create_time", dayEnd)
                .eq("delete_flag", false)
                .groupBy("DATE_FORMAT(create_time,'%Y-%m-%d')"));
        //预警信息
        QueryWrapper<PregnancyGatherInfo> gatherInfoQueryWrapper = new QueryWrapper<>();
        sysRoleAuthorityService.queryDataAuthority(gatherInfoQueryWrapper);
        List<PregnancyGatherInfo> list = pregnancyGatherInfoService.list(gatherInfoQueryWrapper
                .select("a.gather_time,count(1) AS number FROM (SELECT " +
                        " DATE_FORMAT( gather_time, '%Y-%m-%d' ) AS gather_time,pregnancy_id")
                .gt("abnormal_status", PregnancyStatusEnum.NORMAL.getValue())
                .ge("gather_time", eightDayDate)
                .lt("gather_time", dayEnd)
                .eq("delete_flag", false)
                .groupBy("pregnancy_id, DATE_FORMAT(gather_time,'%Y-%m-%d')")
                .last(") a GROUP BY a.gather_time"));

        //七日前接收孕妇数据
        Integer sevenReceiveNumber = 0;
        //七日前预警数据
        Integer sevenEarlyNumber = 0;
        //八日前接收孕妇数据
        Integer eightReceiveNumber = 0;
        //设置数量
        AtomicInteger sevenReceiveNumberSum = new AtomicInteger(0);
        for (PregnancyUser pregnancyUser : userList) {
            //近七日数据
            if (pregnancyUser.getCreateTime().getTime() >= sixDayDate.getTime()) {
                //待产数据
                sevenReceiveNumberSum.addAndGet(pregnancyUser.getNumber());
            }
            //今日数据
            if (pregnancyUser.getCreateTime().getTime() == date.getTime()) {
                //待产数据
                resp.setReceiveNumber(pregnancyUser.getNumber());
            }
            //昨日接收孕妇数据
            if (pregnancyUser.getCreateTime().getTime() == oneDayDate.getTime()) {
                resp.setOldReceiveNumber(pregnancyUser.getNumber());
            }
            //八日前接收孕妇数据
            if (pregnancyUser.getCreateTime().getTime() == eightDayDate.getTime()) {
                eightReceiveNumber = pregnancyUser.getNumber();
            }
            //七日前接收孕妇数据
            if (pregnancyUser.getCreateTime().getTime() == sevenDayDate.getTime()) {
                sevenReceiveNumber = pregnancyUser.getNumber();

            }
        }
        resp.setSevenReceiveNumber(sevenReceiveNumberSum.get());
        AtomicInteger sevenEarlyNumberSum = new AtomicInteger(0);
        for (PregnancyGatherInfo gatherInfo : list) {
            //近七日数据
            if (gatherInfo.getGatherTime().getTime() >= sixDayDate.getTime()) {
                //预警数据
                sevenEarlyNumberSum.addAndGet(gatherInfo.getNumber());
            }
            //今日数据
            if (gatherInfo.getGatherTime().getTime() == date.getTime()) {
                //预警数据
                resp.setEarlyNumber(gatherInfo.getNumber());

            }
            //七日前接收孕妇数据
            if (gatherInfo.getGatherTime().getTime() == sevenDayDate.getTime()) {
                //预警数据
                sevenEarlyNumber = gatherInfo.getNumber();
            }
        }
        resp.setSevenEarlyNumber(sevenEarlyNumberSum.get());
        //今日待产同比上周
        BigDecimal valueOf = BigDecimal.valueOf(100);
        BigDecimal bigDecimal = BigDecimal.valueOf(sevenReceiveNumber);
        BigDecimal sevenValue;
        if (bigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            sevenValue = BigDecimal.valueOf((resp.getReceiveNumber() - sevenReceiveNumber)).multiply(valueOf);
        } else {
            sevenValue = BigDecimal.valueOf((resp.getReceiveNumber() - sevenReceiveNumber)).divide(BigDecimal.valueOf(sevenReceiveNumber), 2, BigDecimal.ROUND_DOWN).multiply(valueOf);
        }
        resp.setReceiveContrastNumber(sevenValue + "%");
        resp.setReceiveContrastStatus(sevenValue.compareTo(BigDecimal.ZERO));
        //昨日待产同比上周
        BigDecimal sevenOldValue = getBigDecimal(resp.getOldReceiveNumber(), eightReceiveNumber, valueOf);
        resp.setOldReceiveContrastNumber(sevenOldValue + "%");
        resp.setOldReceiveContrastStatus(sevenOldValue.compareTo(BigDecimal.ZERO));
        //预警同比上周
        BigDecimal sevenEarlyValue = getBigDecimal(resp.getEarlyNumber(), eightReceiveNumber, valueOf);
        resp.setEarlyContrastNumber(sevenEarlyValue + "%");
        resp.setEarlyContrastStatus(sevenEarlyValue.compareTo(BigDecimal.ZERO));


        return GlobalResultStatus.SUCCESS.toResult().response(resp);
    }

    @Override
    public ResponseResult<PregnancyAdminDataResp> adminQueryStatisticsData() {
        String end = " 00:00:00";
        LocalDate date = LocalDate.now();
        // 获取当前月的第一天
        String firstDay = date.with(TemporalAdjusters.firstDayOfMonth()) + end;
        // 获取当前月的最后一天
        String lastDay = date.with(TemporalAdjusters.lastDayOfMonth()) + end;
        // 当前月份减1
        LocalDate lastMonth = date.minusMonths(1);
        // 获取当前月的第一天
        String lastFirstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth()) + end;
        // 获取当前月的最后一天
        String lastEndDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth()) + end;
        PregnancyAdminDataResp resp = new PregnancyAdminDataResp();
        //月统计数据
        BigDecimal valueOf = BigDecimal.valueOf(100);

        //本月接待人数
        setReceiveInfo(firstDay, lastDay, lastFirstDay, lastEndDay, resp,valueOf);

        //本月顺产总人次（采集无异常的出院孕妇）


        //最近一周采集分析

        //采集时段分析

        return null;
    }


    private void setReceiveInfo(String firstDay, String lastDay, String lastFirstDay, String lastEndDay, PregnancyAdminDataResp resp,BigDecimal valueOf) {
        long receptionNumber = pregnancyUserService.count(new QueryWrapper<PregnancyUser>()
                .lambda()
                .ge(PregnancyUser::getCreateTime, firstDay)
                .le(PregnancyUser::getCreateTime, lastDay)
        );
        //上月接待人数
        long lastReception = pregnancyUserService.count(new QueryWrapper<PregnancyUser>()
                .lambda()
                .ge(PregnancyUser::getCreateTime, lastFirstDay)
                .le(PregnancyUser::getCreateTime, lastEndDay)
        );
        //接待人数同比上月
        BigDecimal lastReceptionNumber = getBigDecimal(receptionNumber, lastReception, valueOf);
        resp.setLastReceptionNumber(lastReceptionNumber);
        resp.setReceiveContrastStatus(lastReceptionNumber.compareTo(BigDecimal.ZERO));
    }

    /**
     * 设置最后想
     *
     * @param receptionNumber
     * @param lastReception
     * @param valueOf
     * @return
     */
    private BigDecimal getBigDecimal(long receptionNumber, long lastReception, BigDecimal valueOf) {
        BigDecimal lastReceptionBig = BigDecimal.valueOf(lastReception);
        BigDecimal lastReceptionNumber;
        if (lastReceptionBig.compareTo(BigDecimal.ZERO) == 0) {
            lastReceptionNumber = BigDecimal.valueOf((receptionNumber - receptionNumber)).multiply(valueOf);
        } else {
            lastReceptionNumber = BigDecimal.valueOf((receptionNumber - lastReception)).divide(lastReceptionBig, 2, BigDecimal.ROUND_DOWN).multiply(valueOf);
        }
        return lastReceptionNumber;
    }

    @Override
    public ResponseResult<PregnancyHomeInfoResp> gatherUserInfoQuery() {
        PregnancyHomeInfoResp resp = new PregnancyHomeInfoResp();
        PregnancyGatherUserPageReq req = new PregnancyGatherUserPageReq();
        req.setPageNo(1);
        req.setPageSize(5);
        req.setStatus(PregnancyStatusEnum.NORMAL.getValue());
        //今日待产
        resp.setExpectantInfo(pregnancyUserService.gatherUserPageList(req));
        //今日预警
        req.setStatus(PregnancyStatusEnum.EARLY.getValue());
        resp.setEarlyInfo(pregnancyUserService.gatherUserPageList(req));
        //今日危险
        req.setStatus(PregnancyStatusEnum.RISK.getValue());
        resp.setRiskInfo(pregnancyUserService.gatherUserPageList(req));
        return GlobalResultStatus.SUCCESS.toResult().response(resp);
    }


}
